package com.wxc;

import com.wxc.common.User;
import com.wxc.controller.UserController;
import com.wxc.thread.ConnectionThread;
import com.wxc.thread.ManageConnectionThreads;
import com.wxc.thread.PushMessageThread;
import com.wxc.util.ConnectionUtil;
import com.wxc.util.SocketUtil;
import com.wxc.vo.Message;
import com.wxc.vo.Resp;
import com.wxc.vo.RespCode;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author wxc
 * @date 2021年10月01日 17:58
 */
@Slf4j
public class QQServer {

    private static final ConnectionUtil connectionUtil = new ConnectionUtil();
    private static final ExecutorService pool = Executors.newFixedThreadPool(1);
    private static final PushMessageThread pushMessageThread = new PushMessageThread();

    public static void run() {
        ServerSocket serverSocket = SocketUtil.startServer();
        // Server send push message
        pushMessageThread.start();
        while (true) {
            Socket socket = null;
            try {
                socket = serverSocket.accept();
            } catch (IOException e) {
                log.warn(e.getMessage());
                continue;
            }
            Message<User> receiveMessage = connectionUtil.receive(socket);
            User user = receiveMessage.getData();
            log.info("Client send Authentication request username:{}", user.getUserName());
            // Authentication success
            Message<Resp<String>> sendMessage = new Message<>();
            sendMessage.setType(Message.MessageType.LOGIN);
            if (UserController.checkUser(user)) {
                // change status
                user.setLoginStatus(true);
                // send Authentication success response
                sendMessage.setData(new Resp<>(null, RespCode.SUCCESS));

                connectionUtil.send(socket, sendMessage);
                // create thread
                ConnectionThread thread = new ConnectionThread(socket, user);
                // execute
                pool.execute(thread);
            } else {
                sendMessage.setData(new Resp<>(null, RespCode.LOGIN_ERROR));
                connectionUtil.send(socket, sendMessage);
                SocketUtil.close(socket);
            }
        }
    }

}
